package com.happy3w.java.ext;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

public class IgnoreUtf8BomInputStream extends InputStream {
    public static final byte[] BOM = new byte[]{(byte) 0xef, (byte) 0xbb, (byte) 0xbf};
    private final InputStream innerStream;
    private Step curStep = new ReadBomStep();

    public IgnoreUtf8BomInputStream(InputStream innerStream) {
        this.innerStream = innerStream;
    }

    @Override
    public int read() throws IOException {
        return curStep.read();
    }

    private interface Step {
        int read() throws IOException;
    }

    private class ReadBomStep implements Step {

        @Override
        public int read() throws IOException {
            byte[] bom = new byte[3];
            int size = innerStream.read(bom);
            if (size == 0 || Arrays.equals(bom, BOM)) {
                curStep = new ProxyStep();
            } else {
                curStep = new ByteStep(bom, size);
            }
            return curStep.read();
        }
    }

    private class ProxyStep implements Step {

        @Override
        public int read() throws IOException {
            return innerStream.read();
        }
    }

    private class ByteStep implements Step {
        private final byte[] bs;
        private final int size;
        private int index = 0;

        private ByteStep(byte[] bs, int size) {
            this.bs = bs;
            this.size = size;
        }

        @Override
        public int read() throws IOException {
            if (index < size) {
                int curValue = bs[index];
                index++;
                return curValue;
            }
            curStep = new ProxyStep();
            return curStep.read();
        }
    }
}
